/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cutils/memory.h>

#include <utils/Log.h>

//#include <system/window.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>

#define CHECK_RET() do{ if(ret) \
 printf("error:\t\tline:%d ret:%d\n", __LINE__, ret); \
 else \
    printf("OK:\t\tline:%d ret:%d\n", __LINE__, ret); \
} while(0)

using namespace android;

static int width=1024, height=768;

// Fill an RGBA_8888 formatted surface with a single color.
static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc,
        uint8_t r, uint8_t g, uint8_t b) {
    Surface::SurfaceInfo info;
    sp<Surface> s = sc->getSurface();
    s->lock(&info);
    uint8_t* img = reinterpret_cast<uint8_t*>(info.bits);
    printf("img address:%p\n", img);
    for (uint32_t y = 0; y < info.h; y++) {
        for (uint32_t x = 0; x < info.w; x++) {
            uint8_t* pixel = img + (4 * (y*info.s + x));
            pixel[0] = r;
            pixel[1] = g;
            pixel[2] = b;
            pixel[3] = 255;
        }
    }
    s->unlockAndPost();
}


void testPickBuffer(sp<SurfaceControl> & surfaceControl){
    int slot, ret;
    sp<Fence> fence;
    sp<ISurfaceTexture> mIST =  surfaceControl->getSurface()->getSurfaceTexture();
    sp<GraphicBuffer> buf;

    uint8_t* img = NULL;
    for(int i=0; i<6; i++)  {
                     ret = mIST->dequeueBuffer(&slot, fence, width, height, PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN);
                     printf("dequeueBuffer:%d slot:%d\n", ret, slot);
                     ret = mIST->requestBuffer(slot, &buf);
                    
                    int ret = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
                    // CHECK_RET();
                    printf("buffer address:%d\n", img);
                    memset(img,  256>>i, width*height*4);
                    buf->unlock();

                    int64_t timestamp;
                    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
                    Rect crop(width, height);
                    ISurfaceTexture::QueueBufferOutput output;
                    ISurfaceTexture::QueueBufferInput input(timestamp, crop, NATIVE_WINDOW_SCALING_MODE_FREEZE,
                        0, fence);
                    ret = mIST->queueBuffer(slot, input, &output);
                    // CHECK_RET();
                    sleep(1);
   }
}

void testBuffer(sp<SurfaceControl> & surfaceControl){
    ANativeWindow* window = surfaceControl->getSurface().get();
    int err = native_window_set_buffer_count(window, 2);
    printf("set buffer count:%d\n", err);

    for(int i=0;i<8;i++)
       fillSurfaceRGBA8(surfaceControl, 0, i*256/8,128);
}

int main(int argc, char** argv)
{
    printf("entry main\n");

    // create a client to surfaceflinger
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
    
    sp<SurfaceControl> surfaceControl = client->createSurface(
            String8("surface"), width, height, PIXEL_FORMAT_RGBA_8888, 0);
    SurfaceComposerClient::openGlobalTransaction();
    surfaceControl->setLayer(100000);
    SurfaceComposerClient::closeGlobalTransaction();

     
    testPickBuffer(surfaceControl);

    // testBuffer(surfaceControl);

    printf("test complete. CTRL+C to finish.\n");

    sleep(5);

    return 0;
}
